//
// Created by hamlet on 2022/1/14.
//

#ifndef SNAKE_GAME_MESSAGEUTIL_H
#define SNAKE_GAME_MESSAGEUTIL_H

#include <vector>
#include "message.h"
#include "room.h"
#include "snakegame.h"

class PlayerInfo;

class DeleteRoomMessage : public Message {
public:
    explicit DeleteRoomMessage(qint64 room_id);
    ~DeleteRoomMessage() override = default;
    static DeleteRoomMessage *parseJson(const QJsonObject &json);
    [[nodiscard]] QJsonObject toJson() const override;

    const qint64 p_roomID;
};

class AllPlayerInfo : public Message {
public:
    explicit AllPlayerInfo(const std::vector<PlayerInfo *> &playerList);
    ~AllPlayerInfo() override;

    static AllPlayerInfo *parseJson(const QJsonObject &json);
    [[nodiscard]] QJsonObject toJson() const override;

    const std::vector<PlayerInfo*> &p_playerList;
    void GIVE_OWNERSHIP();  // 调用此函数后，清空m_playerList，并不释放所有PlayerInfo

private:
    std::vector<PlayerInfo*> *m_playerList = nullptr;
};

class NewPlayerMessage : public Message {
public:
    explicit NewPlayerMessage(const PlayerInfo *player);
    ~NewPlayerMessage() override;

    static NewPlayerMessage *parseJson(const QJsonObject &json);
    [[nodiscard]] QJsonObject toJson() const override;

    const PlayerInfo *p_player;
    PlayerInfo *GIVE_OWNERSHIP();

private:
    PlayerInfo *m_player = nullptr;
};

class DeletePlayerMessage : public Message {
public:
    explicit DeletePlayerMessage(qint64 player_id);
    ~DeletePlayerMessage() override = default;
    static DeletePlayerMessage *parseJson(const QJsonObject &json);
    [[nodiscard]] QJsonObject toJson() const override;

    const qint64 p_playerID;
};

class TextMessage : public Message {
public:
    explicit TextMessage(const QString &text);
    ~TextMessage() override;

    static TextMessage *parseJson(const QJsonObject &json);
    [[nodiscard]] QJsonObject toJson() const override;

    const QString &p_text;

private:
    QString *m_text = nullptr;
};

class SnakeDirectionChangeMessage : public Message {
public:
    explicit SnakeDirectionChangeMessage(qint64 player_id, Snake::Direction direction, int time_stamp);
    ~SnakeDirectionChangeMessage() override = default;
    static SnakeDirectionChangeMessage *parseJson(const QJsonObject &json);
    [[nodiscard]] QJsonObject toJson() const override;

    const qint64 p_playerID;
    const Snake::Direction p_direction;
    const int p_timeStamp;
};

class StartGameMessage : public Message {
public:
    explicit StartGameMessage(int time_stamp);
    ~StartGameMessage() override = default;
    static StartGameMessage *parseJson(const QJsonObject &json);
    [[nodiscard]] QJsonObject toJson() const override;

    const int p_timeStamp;
};

class NewFruitMessage : public Message {
public:
    explicit NewFruitMessage(QPoint fruit_pos, RoomInfo::FruitType fruit_type, int time_stamp);
    ~NewFruitMessage() override = default;
    static NewFruitMessage *parseJson(const QJsonObject &json);
    [[nodiscard]] QJsonObject toJson() const override;

    const QPoint p_fruitPos;
    const RoomInfo::FruitType p_fruitType;
    const int p_timeStamp;
};

class UnknownMessage : public Message {
public:
    explicit UnknownMessage();
    ~UnknownMessage() override = default;
    [[nodiscard]] QJsonObject toJson() const override;
};

#endif //SNAKE_GAME_MESSAGEUTIL_H
